package com.csw.android.ffmpegtest.media.base

import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder

class RecordConfig {

    companion object {
        fun fromMic(
            sampleRateInHz: Int = 48000,
            channelConfig: Int = AudioFormat.CHANNEL_IN_MONO,
            audioFormat: Int = AudioFormat.ENCODING_PCM_16BIT
        ): RecordConfig {
            return RecordConfig(
                MediaRecorder.AudioSource.MIC,
                sampleRateInHz,
                channelConfig,
                audioFormat
            )
        }
    }

    /**
     * 音频源 MediaRecorder.AudioSource
     * 用于指定声音采集设备，如
     * MIC 麦克风
     * VOICE_COMMUNICATION 人与人对话沟通的采集，有降噪效果，突出人声
     */
    val audioSource: Int

    /**
     * 采样率，表示一纳秒内的声音采集次数，目前常用的时44100，采样率越高，声音质量越好
     * 96000, 88200, 64000, 48000, 44100,
     * 32000, 24000, 22050, 16000, 12000,
     * 11025, 8000, 7350,
     */
    val sampleRateInHz: Int

    /**
     * 声道配置
     * 配置                              含义        声道数量
     * AudioFormat.CHANNEL_IN_MONO      单（前）声道    1
     * AudioFormat.CHANNEL_IN_STEREO    左右双声道      2
     */
    val channelConfig: Int

    /**
     * 音频编码
     * AudioFormat.ENCODING_PCM_16BIT 16位编码 基本所有设备通用
     * AudioFormat.ENCODING_MP3       采集数据直接编码成mp3
     * AudioFormat.ENCODING_AAC_LC     采集数据直接编码成AAC_LC
     *
     * PCM是音频原始数据，只经过采样，无压缩，存储占用大，带宽占用高
     * MP3是有损压缩格式，通过将人耳不敏感的高频音域进行压缩
     * AAC是MP3的升级版本，用于取代mp3，最多可以做到20：1的压缩率，帧头带有采样等信息，截取文件段落也可正常播
     * 放，目前常用与视频的中的音频编码。
     * 本程序中只采集PCM，音频后续通过mediacodec进行编码，所以这里直接用ENCODING_PCM_16BIT即可
     */
    val encoding: Int

    constructor(builder: Builder?) : this(
        builder?.audioSource ?: MediaRecorder.AudioSource.MIC,
        builder?.sampleRateInHz ?: 48000,
        builder?.channelConfig ?: AudioFormat.CHANNEL_IN_MONO,
        builder?.encoding ?: AudioFormat.ENCODING_PCM_16BIT,
    )

    constructor(
        audioSource: Int,
        sampleRateInHz: Int,
        channelConfig: Int,
        encoding: Int
    ) {
        this.audioSource = audioSource
        this.sampleRateInHz = sampleRateInHz
        this.channelConfig = channelConfig
        this.encoding = encoding
    }

    /**
     * 获取最小的缓冲区尺寸
     */
    fun getMinBufferSize(): Int {
        return AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, encoding)
    }

    /**
     * 获取声道数量
     */
    fun getChannelCount(): Int {
        return when (channelConfig) {
            AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.CHANNEL_IN_MONO -> 1
            else -> 2
        }
    }

    /**
     * 获取PCM每秒录制多少字节
     * 48000*2*2
     */
    fun getPCMByteRate(): Int {
        val unitByteCount = when (encoding) {
            AudioFormat.ENCODING_PCM_16BIT -> 16 / 8
            else -> 8 / 8
        }
        return unitByteCount * sampleRateInHz * getChannelCount()
    }

    class Builder {
        var audioSource: Int? = null
        var sampleRateInHz: Int? = null
        var channelConfig: Int? = null
        var encoding: Int? = null

        fun build(): RecordConfig {
            return RecordConfig(this)
        }
    }

}